package cn.yh.nft.turbo.base.utils;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: HttpUtils
 * @Author: 草莓爱上啵啵
 *   HttpUtils
 */
public class HttpUtils {

    /**
     *  get
     * @param host 地址
     * @param path 地址路径
     * @param method 方法
     * @param headers 头部信息
     * @param querys  数据
     * @return 返回响应对象
     * @throws Exception  抛出异常
     */
    public static HttpResponse doGet(String host, String path, String method,
                                     Map<String,String> headers,
                                     Map<String,String> querys)throws Exception{
        HttpClient httpClient = wrapClient(host);

        HttpGet request = new HttpGet(buildUrl(host,path,querys));
        for(Map.Entry<String,String> e : headers.entrySet()){
            request.addHeader(e.getKey(),e.getValue());
        }

        return httpClient.execute(request);
    }


    /**
     * Post String
     * @param host 地址
     * @param path 地址路径
     * @param method 方法
     * @param headers 头部信息
     * @param querys 数据
     * @param body 体部信息
     * @return 返回响应对象
     * @throws Exception 抛出异常
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String,String> headers,
                                      Map<String,String> querys,
                                      String body)throws Exception{

        HttpClient httpClient = wrapClient(host);

        HttpPost request = new HttpPost(buildUrl(host,path,querys));
        for (Map.Entry<String, String> e : headers.entrySet()) {
            request.addHeader(e.getKey(),e.getValue());
        }

        if(StringUtils.isNotBlank(body)){
            request.setEntity(new StringEntity(body, "utf-8"));
        }

        return httpClient.execute(request);

    }

    /**
     *  post form 表单
     * @param host 地址
     * @param path 地址路径
     * @param method 方法
     * @param headers 头部信息
     * @param querys 数据
     * @param bodys 请求体信息
     * @return 返回响应对象
     * @throws Exception 抛出异常
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String,String> headers,
                                      Map<String,String> querys,
                                      Map<String,String> bodys) throws Exception{
        HttpClient httpClient = wrapClient(host);

        HttpPost request = new HttpPost(buildUrl(host,path,querys));

        for(Map.Entry<String,String> e : headers.entrySet()){
            request.addHeader(e.getKey(),e.getValue());
        }

        if(null != bodys){
            List<NameValuePair> nameValuePairList = new ArrayList<>();
            for (String key : bodys.keySet()) {
                nameValuePairList.add(new BasicNameValuePair(key,bodys.get(key)));
            }

            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList,"utf-8");
            formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
            request.setEntity(formEntity);
        }

        return httpClient.execute(request);

    }

    /**
     * Post stream
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPost(String host, String path, String method,
                                      Map<String,String> headers,
                                      Map<String,String> querys,
                                      byte[] body) throws Exception{
        HttpClient httpClient = wrapClient(host);

        HttpPost request = new HttpPost(buildUrl(host,path,querys));

        for (Map.Entry<String,String> e : headers.entrySet()){
            request.addHeader(e.getKey(),e.getValue());
        }

        if(null != body){
            request.setEntity(new ByteArrayEntity(body));
        }

        return httpClient.execute(request);
    }

    /**
     * Put Stream
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPut(String host, String path, String method,
                                     Map<String, String> headers,
                                     Map<String, String> querys,
                                     byte[] body) throws Exception{
        HttpClient httpClient = wrapClient(host);

        HttpPut request = new HttpPut(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()){
            request.addHeader(e.getKey(),e.getValue());
        }
        if (null != body){
            request.setEntity(new ByteArrayEntity(body));
        }

        return httpClient.execute(request);

    }

    /**
     *   Put String
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @param body
     * @return
     * @throws Exception
     */
    public static HttpResponse doPut(String host, String path, String method,
                                    Map<String, String> headers,
                                    Map<String, String> querys,
                                    String body) throws Exception{
        HttpClient httpClient = wrapClient(host);

        HttpPut request = new HttpPut(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()){
            request.addHeader(e.getKey(),e.getValue());
        }

        if (StringUtils.isNotBlank(body)){
            request.setEntity(new StringEntity(body,"utf-8"));
        }

        return httpClient.execute(request);
    }


    /**
     *   Delete
     * @param host
     * @param path
     * @param method
     * @param headers
     * @param querys
     * @return
     * @throws Exception
     */
    public static HttpResponse doDelete(String host, String path, String method,
                                        Map<String, String> headers,
                                        Map<String, String> querys)throws Exception{

        HttpClient httpClient = wrapClient(host);

        HttpDelete request = new HttpDelete(buildUrl(host, path, querys));
        for (Map.Entry<String, String> e : headers.entrySet()){
            request.addHeader(e.getKey(),e.getValue());
        }

        return httpClient.execute(request);

    }

    private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException{
        StringBuilder sbUrl = new StringBuilder();
        sbUrl.append(host);
        if(!StringUtils.isBlank(path)){
            sbUrl.append(path);
        }
        if(null != querys){
            StringBuilder sbQuery = new StringBuilder();
            for (Map.Entry<String,String> query : querys.entrySet()){

                if (0 > sbQuery.length()){
                    sbQuery.append("&");
                }

                if(StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())){
                    sbQuery.append(query.getValue());
                }

                if(!StringUtils.isBlank(query.getKey())){
                    sbQuery.append(query.getKey());
                    if(!StringUtils.isBlank(query.getValue())){
                        sbQuery.append("=");
                        sbQuery.append(URLEncoder.encode(query.getValue(),"utf-8"));
                    }
                }
            }
            if (!sbQuery.isEmpty()) {
                sbUrl.append("?").append(sbQuery);
            }
        }
        return sbUrl.toString();
    }

    public static HttpClient wrapClient(String host){
        return HttpClientBuilder.create().build();
    }
}
